#include "io_server_test.h"
#include <iostream>
#include <boost/thread.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/bind.hpp>
#include "task_proccessor.h"
#include "echo_server_test.h"

boost::mutex global_stream_lock;

void IOServerTest::Run()
{
    boost::asio::io_service io;
    boost::asio::deadline_timer t(io,boost::posix_time::seconds(1));
    t.async_wait(IOServerTest::Print);
    std::cout << "[" << boost::this_thread::get_id()<<"]"<<std::endl;
    io.post(boost::bind(&IOServerTest::Show,1));
    io.run();


    boost::shared_ptr<boost::asio::io_service> io_service(new boost::asio::io_service);
    boost::shared_ptr<boost::asio::io_service::work> work(new boost::asio::io_service::work(*io_service));
    boost::asio::io_service::strand strand(*io_service);
    global_stream_lock.lock();
    std::cout<<"["<<boost::this_thread::get_id()<<"] start main thread"<<std::endl;
    global_stream_lock.unlock();
    std::vector<std::thread> work_threads;
    for(int i = 0; i < 4; i++)
    {
        work_threads.emplace_back(std::thread(boost::bind(&IOServerTest::WorkerThread,io_service)));
    }
    work_threads.emplace_back(std::thread(boost::bind(&IOServerTest::ProducerThread,io_service)));
    boost::this_thread::sleep(boost::posix_time::milliseconds(100));
    for(int i = 0; i < 100;i++)
    {
        io_service->post(boost::bind(&IOServerTest::Show,i));
    }
   // boost::this_thread::sleep(boost::posix_time::seconds(10));
    work.reset();
    for (auto& thread : work_threads)
        if (thread.joinable())
            thread.join();

    std::uint16_t port = 8964;
    boost::asio::io_context ioc;
    Server server(ioc,port);
    ioc.run();

    //----------------------------------------------taks_test----------------------------------------------------------//
    task_processor::get().push_task(boost::bind(&IOServerTest::Show,10000000));
    task_processor::get().start();
    task_processor::get().stop();
}
void IOServerTest::DoShow()
{
    std::cout<<"If I were king, I would rule the world"<<std::endl;
}
void IOServerTest::Show(int i)
{
    global_stream_lock.lock();
    std::cout<<"hello world! Show():"<<i<<std::endl;
    std::cout << "[" << boost::this_thread::get_id()<<"]"<<std::endl;
    global_stream_lock.unlock();
}
void IOServerTest::Print( const boost::system::error_code &ec )
{
    std::cout<<"hello world!"<<std::endl;
    std::cout << "[" << boost::this_thread::get_id()<<"]"<<std::endl;
}

void IOServerTest::ProducerThread(boost::shared_ptr< boost::asio::io_service > io_service)
{
    int beg = 0;
    while(1)
    {
        if(beg > 10)
            break;
        for(int i = 0; i < 100;i++)
        {
            io_service->post(boost::bind(&IOServerTest::Show,i+beg));
            beg++;
        }
        boost::this_thread::sleep(boost::posix_time::seconds(1)); 
    }
}
void IOServerTest::WorkerThread( boost::shared_ptr< boost::asio::io_service > io_service )
{

    global_stream_lock.lock();
    auto now = boost::posix_time::microsec_clock::universal_time();
    std::cout << "[" << boost::this_thread::get_id() << "] Thread Start Time:" << now<< std::endl;
    global_stream_lock.unlock();

    io_service->run();

    global_stream_lock.lock();
    auto end = boost::posix_time::microsec_clock::universal_time();
    auto elapse = end - now;
    std::cout << "[" << boost::this_thread::get_id()
        << "] Thread Finish milliseconds:" <<elapse.ticks()<<"\tsecond:"<<elapse.total_seconds()<< std::endl;
    global_stream_lock.unlock();
}
